mod huarongdao;
use crate::huarongdao::{State, Move};
use std::{io::stdin, time::Duration, thread::sleep, sync::{atomic::{AtomicBool, Ordering}, mpsc}, env::args};
#[cfg(not(target_arch = "wasm32"))]
use device_query::{DeviceState, DeviceEvents};

static GOON: AtomicBool = AtomicBool::new(true);
static BASE_TIP: &str = "请输入[0~9]选择要移动的棋子......";

enum Message {
  Quit,
  Move(Move),
  Say(String),
  Continue,
  Reset,
}

fn key_handler(key: &str, state: State) -> Message {
  if key == "Q" {
    Message::Quit
  } else if key == "S" {
    Message::Say(state.short_show())
  } else if key == "R" {
    Message::Reset
  } else if key.starts_with("Key") {
    let num = key[3..4].parse::<u8>().unwrap();
    let canmove = state.find_move(num);
    if canmove.len() > 0  {
      Message::Move(canmove[0])
    } else {
      Message::Say(format!("{}号棋子当前不可移动, 请选择旁边有空格的棋子......", num))
    }
  } else {
    Message::Continue
  }
}

#[cfg(not(target_arch = "wasm32"))]
fn main() {
  let mut s: State = if args().len() == 1 {State::new()} else {
    let arr = args().nth(1).unwrap().split(",")
      .map(|s|{s.parse::<u8>().unwrap()}).collect::<Vec<u8>>();
    let arr: [u8; 12] = arr.try_into().unwrap();
    State::from_array(arr as [u8; 12])
  };
  let start = s.clone();
  let (tx, rx) = mpsc::sync_channel::<String>(5);


  let device_state = DeviceState::new();

  let _guard = device_state.on_key_up(move |key| {
    tx.send(key.to_string()).unwrap();
  });

  while GOON.load(Ordering::Relaxed) {
    println!("\n\n{s}\n您已移动了{}步, {BASE_TIP}", s.step_no);
    let key = rx.recv().unwrap();
    {
      match key_handler(&key.to_string(), s) {
        Message::Quit => {GOON.store(false, Ordering::Relaxed);},
        Message::Say(msg) => {println!("\n{s}\n{msg}");},
        Message::Move(m) => {if s.do_move(m) {println!("\n{s}\n您成功的帮助关羽释放了曹操, 可喜可贺!"); break;};},
        Message::Continue => {},
        Message::Reset => {s = start.clone(); println!("\n\n您选择了重置游戏.");}
      }
    }
    sleep(Duration::from_millis(1));
  };

  println!("\n游戏结束,请按回车键退出.");
  let mut wait_string = String::new();
  stdin().read_line(&mut wait_string).unwrap();
}
